var logger = require('pomelo-logger').getLogger(__filename);
var DateUtil = require("../../../utils/dateUtil");

module.exports = function(app) {
    return new Remote(app);
};

var Remote = function(app) {
    this.app = app;
};

//"tencent", uid, itemId, num, "tencent"
Remote.prototype.recharge = function(msgData, callback) {
    logger.info("recharge by msgData: %s", JSON.stringify(msgData));
    var channel = msgData.channel;
    var uid = msgData.uid;
    var itemIndex = msgData.itemIndex;
    var orderId = msgData.orderId;
    var totalFee = msgData.totalFee;
    var rechargeType = msgData.rechargeType;
    var params = {};
    params.uid = uid;
    params.orderId = orderId;
    params.totalFee = totalFee;
    params.channel = channel;
    params.time = Date.now();
    params.orderState = 3;
    params.payPlat = rechargeType;
    // 订单去重
    var self = this;
    var orderDao = this.app.get("orderDao");
    orderDao.insertOrder(params, function(error) {
        if (!!error) {
            logger.warn("recharge. duplicate orderId, channel: %s, orderId: %s", channel, orderId);
            logger.warn("recharge. duplicate orderId, error: %s", JSON.stringify(error));
            callback("recharge failed, error: duplicate orderId");
            return;
        }

        logger.info("rechargeType: %s", rechargeType);
        logger.info("totalFee: %s", totalFee);
        if (rechargeType == 'wechat') {
            self.rechargeByTencent(uid, itemIndex, totalFee, channel, function(error) {
                logger.info("rechargeByTencent callback: %s", error);
                if (!!error) {
                    callback("fail");
                    return;
                }
                callback("success");
            });
        } else if (rechargeType == 'wyw') {
            self.rechargeByWyw(uid, itemIndex, totalFee, channel, function(error) {
                logger.info("rechargeByWyw callback: %s", error);
                if (!!error) {
                    callback("fail");
                    return;
                }
                callback("success");
            });
        }
    });
};

//腾讯支付
Remote.prototype.rechargeByTencent = function(uid, itemIndex, totalFee, channel, callback) {
    logger.info("rechargeByTencent, uid: %s, itemIndex: %s, totalFee: %s, channel: %s", uid, itemIndex, totalFee, channel);
    var self = this;
    var playerService = this.app.get("playerService");
    playerService.findByUid(uid, function (player){
        logger.info("rechargeByTencent findByUid: " + JSON.stringify(player));
        if(!player){
            logger.error("rechargeByTencent, invalid uid: %s", uid);
            callback("invalid uid");
            return;
        }
        // TODO:做更多有效性验证
        // 校验itemIndex和实际收到金额有效性
        var shopConfig = require('../../../../config/goods').rmb2Diamond;
        var orderItem = shopConfig[itemIndex];
        if (!orderItem){
            callback("invalid itemIndex");
            return;
        }
        // 单日最高额度限制
        var configService = self.app.get("configService");
        var dailyLimit = parseInt(configService.getEnableConfigValueByKey("rechargeLimit"));
        dailyLimit = dailyLimit ? dailyLimit : 3000;
        if (player.getDailyRecharge() > dailyLimit) {
            logger.info("player : %s， recharge limit, daily max limit.", player.getNickname());
            callback(JSON.stringify({resultCode : -108, msg : "已达当日充值上限！"}));
            return;
        }
        // totalFee分为单位，如果实际充值totalFee小于配置的80%，认为该笔充值存在问题
        if (false && totalFee < orderItem.price * 100 * 0.8) {
            logger.error("illegal recharge with itemindex: %s, total fee: %s", itemIndex, totalFee);
            callback(JSON.stringify({resultCode : -101, msg : "illegal recharge"}));
            return;
        }
        logger.info("player current diamond %s.", player.getDiamond());
        var rechargedDiamond = orderItem.money + orderItem.extra;
        logger.info("rechargedDiamond %s.", rechargedDiamond);
        if (!rechargedDiamond || rechargedDiamond < 0) {
            logger.error("recharge config error. itemindex: %s, rechargedDiamond: %s", itemIndex, rechargedDiamond);
            callback("recharge config error.");
            return;
        }
        // 给玩家加钱
        player.changeDiamond(rechargedDiamond);
        player.changeDailyRecharge(player.getDailyRecharge() + orderItem.price);
        player.addTotalRecharge(player.getDailyRecharge() + orderItem.price);
        logger.info("diamond after recharge-------------- %s.", player.getDiamond());
        logger.info("player %s, uid=%d, diamond change by recharge : %s , from %s to %s.", player.getNickname(), player.getUid(),
            rechargedDiamond, player.getDiamond() - rechargedDiamond, player.getDiamond());
        // 写入数据库
        var playerService = self.app.get("playerService");
        playerService.save(player);
        logger.info("changeDiamond after save -------------- %s.", player.getDiamond());
        // 通知客户端
        if(player.isOnline()){
            player.pushUpdateSelfCurrency();
        }
        logger.info("rechargeByTencent callback--------------.");
        callback(null, player);
        // TODO: 同步代理GM服
        // 用户充值 发送mq
        let amqpService = self.app.get("amqpService");
        let exchange = 'kd_game_log_ex';
        let routeKey = 'game_log';
        let msg = {
            type : 'user_payment',
            uid : player.getUid(),
            currencyType : 'diamond',
            amount: rechargedDiamond,
            time : DateUtil.nowMS(),
            channel : player.getUserChannel()
        };
        amqpService.sendMsg(exchange, routeKey, msg);
    });
};

// 玩一玩
Remote.prototype.rechargeByWyw = function(uid, itemIndex, totalFee, channel, callback) {
    logger.info("rechargeByWyw, uid: %s, itemIndex: %s, totalFee: %s, channel: %s", uid, itemIndex, totalFee, channel);
    var self = this;
    var playerService = this.app.get("playerService");
    playerService.findByUid(uid, function (player){
        logger.info("rechargeByWyw findByUid: " + JSON.stringify(player));
        if(!player){
            logger.error("rechargeByWyw, invalid uid: %s", uid);
            callback("invalid uid");
            return;
        }
        // TODO:做更多有效性验证
        // 校验itemIndex和实际收到金额有效性
        var shopConfig = require('../../../../config/goods').rmb2DiamondWyx;
        var orderItem = shopConfig[itemIndex];
        if (!orderItem){
            callback("invalid itemIndex");
            return;
        }
        // 单日最高额度限制
        var configService = self.app.get("configService");
        var dailyLimit = parseInt(configService.getEnableConfigValueByKey("rechargeLimit"));
        dailyLimit = dailyLimit ? dailyLimit : 3000;
        if (player.getDailyRecharge() > dailyLimit) {
            logger.info("player : %s， recharge limit, daily max limit.", player.getNickname());
            callback(JSON.stringify({resultCode : -108, msg : "已达当日充值上限！"}));
            return;
        }
        // totalFee分为单位，如果实际充值totalFee小于配置的80%，认为该笔充值存在问题
        if (false && totalFee < orderItem.price * 100 * 0.8) {
            logger.error("illegal recharge with itemindex: %s, total fee: %s", itemIndex, totalFee);
            callback(JSON.stringify({resultCode : -101, msg : "illegal recharge"}));
            return;
        }
        logger.info("player current diamond %s.", player.getDiamond());
        var rechargedDiamond = orderItem.money + orderItem.extra;
        logger.info("rechargedDiamond %s.", rechargedDiamond);
        if (!rechargedDiamond || rechargedDiamond < 0) {
            logger.error("recharge config error. itemindex: %s, rechargedDiamond: %s", itemIndex, rechargedDiamond);
            callback("recharge config error.");
            return;
        }
        // 给玩家加钱
        player.changeDiamond(rechargedDiamond);
        player.changeDailyRecharge(player.getDailyRecharge() + orderItem.price);
        player.addTotalRecharge(player.getDailyRecharge() + orderItem.price);
        logger.info("diamond after recharge-------------- %s.", player.getDiamond());
        logger.info("player %s, uid=%d, diamond change by recharge : %s , from %s to %s.", player.getNickname(), player.getUid(),
            rechargedDiamond, player.getDiamond() - rechargedDiamond, player.getDiamond());
        // 写入数据库
        var playerService = self.app.get("playerService");
        playerService.save(player);
        logger.info("changeDiamond after save -------------- %s.", player.getDiamond());
        // 通知客户端
        if(player.isOnline()){
            player.pushUpdateSelfCurrency();
        }
        logger.info("rechargeByWyw callback--------------.");
        callback(null, player);
        // TODO: 同步代理GM服
        // 用户充值 发送mq
        let amqpService = self.app.get("amqpService");
        let exchange = 'kd_game_log_ex';
        let routeKey = 'game_log';
        let msg = {
            type : 'user_payment',
            uid : player.getUid(),
            currencyType : 'diamond',
            amount: rechargedDiamond,
            time : DateUtil.nowMS(),
            channel : player.getUserChannel()
        };
        amqpService.sendMsg(exchange, routeKey, msg);
    });
};


// postData.channel = "sft";
// postData.uid = postData["ext1"];
// postData.itemIndex = 0;
// postData.orderId = postData["transNo"];
// postData.totalFee = parseInt(parseFloat(postData["transAmount"]));;
// postData.rechargeType = 'sft';
//盛付通
Remote.prototype.shengfutongRecharge = function(request, callback) {
    logger.info("recharge by request: %s", JSON.stringify(request));
    logger.info("sheng pay recharge. request.body=" + JSON.stringify(request.body));
    let uid = request.body.Ext1;
    let totalFee = parseInt(parseFloat(request.body.TransAmount));
    let tradeState = request.body.TransStatus;
    let orderId = request.body.TransNo;

    if (tradeState !== '01') {
        logger.error("tradeState is not valid. request.body=" + JSON.stringify(request.body));
        callback('fail');
        return;
    }

    if (!uid) {
        logger.error("invalid operator. query=" + JSON.stringify(request.body));
        callback('fail');
        return;
    }

    let body = request.body;
    let keys = ["zhu2bo0zha1jin6hua", "shengfutongzhifumd5gong"];
    let text = body.Name + body.Version + body.Charset + body.TraceNo + body.MsgSender + body.SendTime + body.InstCode + body.OrderNo +
        body.OrderAmount + body.TransNo + body.TransAmount + body.TransStatus + body.TransType + body.TransTime + body.MerchantNo +
        body.Ext1 + body.Ext2 + body.SignType + keys[index];

    let digest = require('crypto').createHash('md5').update(text).digest('hex').toUpperCase();
    if (digest !== request.body.SignMsg) {
        logger.error("sign is not valid. digest=" + digest + " signMsg=" + request.body.SignMsg);
        callback('fail');
        return;
    }

    let params = {
        uid: uid,
        orderId: orderId,
        totalFee: totalFee,
        channel: "shengfutong",
        time: Date.now(),
        orderState: 3,
        payPlat: "shengfutong"
    };
    this.app.get("orderDao").insertOrder(params, error => {
        if (!!error) {
            logger.warn("recharge. duplicate orderId, channel: shengfutong, orderId: %s", orderId);
            logger.warn("recharge. duplicate orderId, error: %s", JSON.stringify(error));
            callback("recharge failed, error: duplicate orderId");
            return;
        }

        logger.info("rechargeType: %s", rechargeType);
        logger.info("totalFee: %s", totalFee);

        let playerService = this.app.get("playerService");
        playerService.findByUid(uid, player => {
            logger.info("shengfutongRecharge findByUid: " + JSON.stringify(player));
            if(!player){
                logger.error("shengfutongRecharge, invalid uid: %s", uid);
                callback("invalid uid");
                return;
            }
            // 单日最高额度限制
            let configService = this.app.get("configService");
            let dailyLimit = parseInt(configService.getEnableConfigValueByKey("rechargeLimit"));
            dailyLimit = dailyLimit ? dailyLimit : 3000;
            if (player.getDailyRecharge() > dailyLimit) {
                logger.info("player : %s， recharge limit, daily max limit.", player.getNickname());
                callback(JSON.stringify({resultCode : -108, msg : "已达当日充值上限！"}));
                return;
            }

            logger.info("player current diamond %s.", player.getDiamond());
            let rechargedDiamond = totalFee * 110;
            logger.info("rechargedDiamond %s.", rechargedDiamond);
            if (!rechargedDiamond || rechargedDiamond < 0) {
                logger.error("recharge config error. itemindex: %s, rechargedDiamond: %s", itemIndex, rechargedDiamond);
                callback("recharge config error.");
                return;
            }
            // 给玩家加钱
            player.changeDiamond(rechargedDiamond);
            player.changeDailyRecharge(player.getDailyRecharge() + totalFee);
            player.addTotalRecharge(player.getDailyRecharge() + totalFee);
            logger.info("diamond after recharge-------------- %s.", player.getDiamond());
            logger.info("player %s, uid=%d, diamond change by recharge : %s , from %s to %s.", player.getNickname(), player.getUid(),
                rechargedDiamond, player.getDiamond() - rechargedDiamond, player.getDiamond());
            // 写入数据库
            playerService.save(player);
            logger.info("changeDiamond after save -------------- %s.", player.getDiamond());
            // 通知客户端
            if(player.isOnline()){
                player.pushUpdateSelfCurrency();
            }
            logger.info("rechargeByTencent callback--------------.");
            callback(null, player);
            // TODO: 同步代理GM服
            // 用户充值 发送mq
            let amqpService = self.app.get("amqpService");
            let exchange = 'kd_game_log_ex';
            let routeKey = 'game_log';
            let msg = {
                type : 'user_payment',
                uid : player.getUid(),
                currencyType : 'diamond',
                amount: rechargedDiamond,
                time : DateUtil.nowMS(),
                channel : player.getUserChannel()
            };
            amqpService.sendMsg(exchange, routeKey, msg);
        });


    });

};